﻿'***********************************************************************
' Assembly         : SOFA.Caching
' Copyright        : (c) Jebarson. All rights reserved.
' Website			: http://www.jebarson.info
'***********************************************************************
Imports System.Reflection

Namespace Caching
    ' TODO: This class has to be moved to the common library
    ''' <summary>
    ''' Manage for object relation methods.
    ''' </summary>
    Friend Class ObjectManager

#Region " Declarations "
        ''' <summary>
        ''' Member variable for object
        ''' </summary>
        Public Shared Instance As New ObjectManager
#End Region

#Region " Constructors "
        ''' <summary>
        ''' Prevents a new instance of the <see cref="ObjectManager" /> class.
        ''' </summary>
        Private Sub New()
        End Sub
#End Region

#Region " Public Methods "
        ''' <summary>
        ''' Loads the object.
        ''' </summary>
        ''' <typeparam name="T">Type of the object.</typeparam>
        ''' <param name="row">The data row from which data has to be loaded.</param>
        ''' <param name="instance">The instance to which the value to be loaded.</param>
        ''' <returns>The loaded object.</returns>
        Public Function LoadObject(Of T)(ByVal row As DataRow, ByVal instance As T) As T
            Dim columnAttributeObject As ColumnMapAttribute
            Dim properties() As PropertyInfo
            Dim valueSet As Boolean

            If row Is Nothing Then
                Return Nothing
            End If

            properties = instance.GetType().GetProperties()

            If properties.Length = 0 Then
                Return instance
            End If

            For Each propertyObject As PropertyInfo In properties
                valueSet = False
                For Each attributeObject As Object In propertyObject.GetCustomAttributes(False)
                    If attributeObject.GetType() Is GetType(ColumnMapAttribute) Then
                        columnAttributeObject = CType(attributeObject, ColumnMapAttribute)
                        If (Not String.IsNullOrEmpty(columnAttributeObject.ColumnName)) Then
                            If row.Table.Columns.Contains(columnAttributeObject.ColumnName) _
                             AndAlso Not row(columnAttributeObject.ColumnName) Is DBNull.Value _
                             AndAlso propertyObject.CanWrite Then

                                propertyObject.SetValue(instance, row(columnAttributeObject.ColumnName), Nothing)
                                valueSet = True
                            End If
                        End If
                    End If
                Next

                If Not valueSet Then
                    If row.Table.Columns.Contains(propertyObject.Name) _
                     AndAlso Not row(propertyObject.Name) Is DBNull.Value _
                     AndAlso propertyObject.CanWrite Then
                        propertyObject.SetValue(instance, row(propertyObject.Name), Nothing)
                    End If
                End If
            Next

            Return instance
        End Function

        ''' <summary>
        ''' Loads the object to a new instance.
        ''' </summary>
        ''' <typeparam name="T">Type of the object.</typeparam>
        ''' <param name="row">The data row from which data has to be loaded.</param>
        ''' <returns>The newly created object.</returns>
        Public Function LoadObject(Of T)(ByVal row As DataRow) As T
            Dim instance As T

            instance = Activator.CreateInstance(Of T)()
            Return Me.LoadObject(row, instance)
        End Function
#End Region
    End Class
End Namespace
